﻿using Core;
using Core.Domain.Customers;
using Services.Security;
using Services.Stores;
using System;
using System.Linq;

namespace Services.Customers
{
    /// <summary>
    /// 用户注册服务实现类
    /// </summary>
    public partial class CustomerRegistrationService : ICustomerRegistrationService
    {

        #region Fields

        private readonly ICustomerService _customerService;
        private readonly IStoreService _storeService;
        private readonly IEncryptionService _encryptionService;
        private readonly CustomerSettings _customerSettings;

        #endregion

        #region Ctor

        /// <summary>
        /// Ctor
        /// </summary>
        public CustomerRegistrationService(ICustomerService customerService,
            IStoreService storeService,
            IEncryptionService encryptionService,
            CustomerSettings customerSettings)
        {
            this._customerService = customerService;
            this._storeService = storeService;
            this._customerSettings = customerSettings;
            this._encryptionService = encryptionService;
        }

        #endregion

        #region Methods

        /// <summary>
        /// 验证用户
        /// </summary>
        /// <returns>Result</returns>
        public virtual CustomerLoginResults ValidateCustomer(string loginName, string password)
        {
            Customer customer = null;
            if (_customerSettings.NameMethod == RegisterMethod.Email)
                customer = _customerService.GetCustomerByEmail(loginName);
            else if (_customerSettings.NameMethod == RegisterMethod.Name)
                customer = _customerService.GetCustomerByUsername(loginName);
            else if (_customerSettings.NameMethod == RegisterMethod.Phone)
                customer = _customerService.GetCustomerByPhone(loginName);

            if (customer == null)
                return CustomerLoginResults.CustomerNotExist;
            if (customer.Deleted)
                return CustomerLoginResults.Deleted;
            if (!customer.Active)
                return CustomerLoginResults.NotActive;
            //only registered can login
            if (!customer.IsRegistered())
                return CustomerLoginResults.NotRegistered;
            
            //pwd = _encryptionService.EncryptText(password);
            string pwd = _encryptionService.CreatePasswordHash(password, customer.PasswordSalt, _customerSettings.HashedPasswordFormat);


            bool isValid = pwd == customer.Password;

            //save last login date
            if (isValid)
            {
                _customerService.UpdateCustomer(customer);
                return CustomerLoginResults.Successful;
            }
            else
                return CustomerLoginResults.WrongPassword;
        }

        /// <summary>
        /// Register customer
        /// </summary>
        /// <param name="request">Request</param>
        /// <returns>Result</returns>
        public virtual CustomerRegistrationResult RegisterCustomer(CustomerRegistrationRequest request)
        {
            if (request == null)
                throw new ArgumentNullException("request");

            if (request.Customer == null)
                throw new ArgumentException("不能读取当前用户");

            var result = new CustomerRegistrationResult();
            if (request.Customer.IsRegistered())
            {
                result.AddError("当前用户已经注册");
                return result;
            }
            if (_customerSettings.NameMethod == RegisterMethod.Email)
            {
                if (String.IsNullOrEmpty(request.Email))
                {
                    result.AddError("请输入Email");
                    return result;
                }
                if (!CommonHelper.IsValidEmail(request.Email))
                {
                    result.AddError("Email格式错误");
                    return result;
                }
            }
            if (String.IsNullOrWhiteSpace(request.Password))
            {
                result.AddError("请输入用户密码");
                return result;
            }
            if (_customerSettings.NameMethod== RegisterMethod.Name)
            {
                if (String.IsNullOrEmpty(request.UserName))
                {
                    result.AddError("请输入登陆用户名");
                    return result;
                }
            }

            if (_customerService.GetCustomerByEmail(request.Email) != null)
            {
                result.AddError("该Email已经注册");
                return result;
            }
            if (_customerSettings.NameMethod== RegisterMethod.Name)
            {
                if (_customerService.GetCustomerByUsername(request.UserName) != null)
                {
                    result.AddError("该用户名已经注册");
                    return result;
                }
            }

            request.Customer.Username = request.UserName;
            request.Customer.Email = request.Email;


            request.Customer.Active = true;

            var registeredRole = _customerService.GetCustomerRoleBySystemRole(SystemRole.Registered);
            if (registeredRole == null)
                throw new Exception("'Register' 权限不能被读取");
            request.Customer.CustomerRole = registeredRole;

            //秘钥
            string saltKey = _encryptionService.CreateSaltKey(5);
            request.Customer.PasswordSalt = saltKey;
            request.Customer.Password = _encryptionService.CreatePasswordHash(request.Password, saltKey, _customerSettings.HashedPasswordFormat);

            _customerService.UpdateCustomer(request.Customer);
            return result;
        }

        /// <summary>
        /// Change password
        /// </summary>
        /// <param name="request">Request</param>
        /// <returns>Result</returns>
        public virtual PasswordChangeResult ChangePassword(ChangePasswordRequest request)
        {
            if (request == null)
                throw new ArgumentNullException("request");

            var result = new PasswordChangeResult();
            if (String.IsNullOrWhiteSpace(request.Email))
            {
                result.AddError("请输入电子Email");
                return result;
            }
            if (String.IsNullOrWhiteSpace(request.NewPassword))
            {
                result.AddError("请输入新密码");
                return result;
            }

            var customer = _customerService.GetCustomerByEmail(request.Email);
            if (customer == null)
            {
                result.AddError("指定的Email没有找到,请从新输入");
                return result;
            }


            var requestIsValid = false;
            if (request.ValidateRequest)
            {
                string oldPwd = _encryptionService.CreatePasswordHash(request.OldPassword, customer.PasswordSalt, _customerSettings.HashedPasswordFormat);
                
                bool oldPasswordIsValid = oldPwd == customer.Password;
                if (!oldPasswordIsValid)
                    result.AddError("当前密码输入错误");

                if (oldPasswordIsValid)
                    requestIsValid = true;
            }
            else
                requestIsValid = true;


            if (requestIsValid)
            {
                _customerService.UpdateCustomer(customer);
            }

            return result;
        }

        /// <summary>
        /// 设置Email
        /// </summary>
        public virtual void SetEmail(Customer customer, string newEmail)
        {
            if (customer == null)
                throw new ArgumentNullException("customer");

            newEmail = newEmail.Trim();
            string oldEmail = customer.Email;

            if (!CommonHelper.IsValidEmail(newEmail))
                throw new Exception("无效的Email");

            if (newEmail.Length > 100)
                throw new Exception("您输入的Email长度超过了100个字符");

            var customer2 = _customerService.GetCustomerByEmail(newEmail);
            if (customer2 != null && customer.Id != customer2.Id)
                throw new Exception("该Email已经被其他用户使用");

            customer.Email = newEmail;
            _customerService.UpdateCustomer(customer);
        }

        /// <summary>
        /// Sets a customer username
        /// </summary>
        /// <param name="customer">Customer</param>
        /// <param name="newUsername">New Username</param>
        public virtual void SetUsername(Customer customer, string newUsername)
        {
            if (customer == null)
                throw new ArgumentNullException("customer");

            if (!_customerSettings.ChangeUsernames)
                throw new Exception("不允许更改用户名");

            newUsername = newUsername.Trim();

            if (newUsername.Length > 100)
                throw new Exception("用户名长度超过了100");

            var user2 = _customerService.GetCustomerByUsername(newUsername);
            if (user2 != null && customer.Id != user2.Id)
                throw new Exception("该用户名已经被其他用户使用");

            customer.Username = newUsername;
            _customerService.UpdateCustomer(customer);
        }


        /// <summary>
        /// 更改手机号
        /// </summary>
        /// <param name="customer"></param>
        /// <param name="newPhone"></param>
        public void SetPhone(Core.Domain.Customers.Customer customer, string newPhone)
        {
            if (customer == null)
                throw new ArgumentNullException("customer");
            
            newPhone = newPhone.Trim();

            if (newPhone.Length > 20)
                throw new Exception("手机号长度超过了20");

            var user2 = _customerService.GetCustomerByPhone(newPhone);
            if (user2 != null && customer.Id != user2.Id)
                throw new Exception("该手机号已经被其他用户使用");

            customer.Phone = newPhone;
            _customerService.UpdateCustomer(customer);
        }
        #endregion


    }
}
